package com.xuyiwei.xblog.core.util;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.OSSObjectSummary;
import com.aliyun.oss.model.ObjectListing;
import com.sun.org.apache.regexp.internal.RE;
import com.xuyiwei.xblog.core.base.constant.consts.DateConst;
import com.xuyiwei.xblog.core.base.constant.enums.FileUploadType;
import com.xuyiwei.xblog.core.support.StrKit;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by xuyiwei on 2018/11/24.
 */
public class OssUtil {
    //阿里云oss endpoint配置
    public static String endpoint = SpringContextHolder.getApplicationContext().getEnvironment()
            .getProperty("oss.endpoint");

    //阿里云oss accessKeyId配置
    public static String accessKeyId = SpringContextHolder.getApplicationContext().getEnvironment()
            .getProperty("oss.accessKeyId");

    //阿里云oss accessKeySecret配置
    public static String accessKeySecret = SpringContextHolder.getApplicationContext().getEnvironment()
            .getProperty("oss.accessKeySecret");

    //阿里云oss bucketName配置
    public static String bucketName = SpringContextHolder.getApplicationContext().getEnvironment()
            .getProperty("oss.bucketName");


    /**
     *
     * @Title: getOSSClient
     * @Description: 获取oss客户端
     * @return OSSClient oss客户端
     * @throws
     */
    public static OSSClient getOSSClient() {
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        return ossClient;
    }


    /**
     *
     * @Title: uploadByInputStream
     * @Description: 通过输入流上传文件
     * @param url 	连接
     * @param fileName 	想保留的附件名
     * @param type 	上传的文件夹类型
     * @return string 		返回类型
     * @throws
     */
    public static String uploadByNetworkStream(URL url,String fileName, FileUploadType type) {
        OSSClient ossClient = getOSSClient();
        try {
            InputStream inputStream = url.openStream();
            String objectName = getObjectName(fileName,type);
            ossClient.putObject(bucketName, objectName, inputStream);
            ossClient.shutdown();
            return objectName;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return null;
    }


    /**
     *
     * @Title: uploadByInputStream
     * @Description: 通过输入流上传文件
     * @param inputStream 	输入流
     * @param fileName 	想保留的附件名
     * @param type 	上传的文件夹类型
     * @return string 		返回类型
     * @throws
     */
    public static String uploadByInputStream(InputStream inputStream, String fileName,
                                           FileUploadType type) {
        OSSClient ossClient = getOSSClient();
        try {
            String objectName = getObjectName(fileName,type);
            ossClient.putObject(bucketName, objectName, inputStream);
            return objectName;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return null;
    }

    /**
     *
     * @Title: uploadByInputStream
     * @Description: 通过输入流上传文件
     * @param file 	输入流
     * @param type 	上传的文件夹类型
     * @return string 		返回类型
     * @throws
     */
    public static String uploadByFile(MultipartFile file, FileUploadType type) {
        OSSClient ossClient = getOSSClient();
        try {
            String objectName = getObjectName(file.getOriginalFilename(),type);
            ossClient.putObject(bucketName, objectName, file.getInputStream());
            return objectName;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return null;
    }

    /**
     *
     * @Title: uploadByInputStream
     * @Description: 通过输入流上传文件
     * @param file 	输入流
     * @param type 	上传的文件夹类型
     * @return string 		返回类型
     * @throws
     */
    public static String uploadByFile(File file,String fileName, FileUploadType type) {
        OSSClient ossClient = getOSSClient();
        try {
            String objectName = getObjectName(fileName,type);
            ossClient.putObject(bucketName, objectName, file);
            return objectName;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return null;
    }



    public static String getObjectName(String fileName,FileUploadType type){
        // 不用时间戳命名文件，改为具体的直观的日期命名文件
        String objectName = DateUtil.date2Str(new Date(), DateConst.MILLISECOND)+"_"+fileName;
        return type.getPath()+objectName;
    }



    /**
     *
     * @Title: deleteFile
     * @Description: 根据key删除oss服务器上的文件
     * @param key    		文件路径/名称，例如“test/a.txt”
     * @return void    		返回类型
     * @throws
     */
    public static void deleteFile(String key) {
        getOSSClient().deleteObject(bucketName, key);
    }


    /**
     *
     * @Title: getInputStreamByOSS
     * @Description:根据key获取服务器上的文件的输入流
     * @param key 			文件路径和名称
     * @return InputStream 	文件输入流
     * @throws
     */
    public static InputStream getInputStreamByOSS(String key) {
        InputStream content = null;
        try {
            OSSObject ossObj = getOSSClient().getObject(bucketName, key);
            content = ossObj.getObjectContent();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return content;
    }

    /**
     *
     * @Title: queryAllObject
     * @Description: 查询某个bucket里面的所有文件
     * @param bucketName		bucket名称
     * @return List<String>  文件路径和大小集合
     * @throws
     */
    public static List<String> queryAllObject(String bucketName) {
        List<String> results = new ArrayList<String>();
        try {
            // ossClient.listObjects返回ObjectListing实例，包含此次listObject请求的返回结果。
            ObjectListing objectListing = getOSSClient().listObjects(bucketName);
            // objectListing.getObjectSummaries获取所有文件的描述信息。
            for (OSSObjectSummary objectSummary : objectListing.getObjectSummaries()) {
                results.add(" - " + objectSummary.getKey() + "  " + "(size = " + objectSummary.getSize() + ")");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (getOSSClient() != null) {
                getOSSClient().shutdown();
            }
        }
        return results;
    }



    /**
     * Description: 判断OSS服务文件上传时文件的contentType
     *
     * @param filenameExtension
     *            文件后缀
     * @return String
     */
    public static String getcontentType(String filenameExtension) {
        if (filenameExtension.equalsIgnoreCase("bmp")) {
            return "image/bmp";
        }
        if (filenameExtension.equalsIgnoreCase("gif")) {
            return "image/gif";
        }
        if (filenameExtension.equalsIgnoreCase("jpeg") || filenameExtension.equalsIgnoreCase("jpg")
                || filenameExtension.equalsIgnoreCase("png")) {
            return "image/jpeg";
        }
        if (filenameExtension.equalsIgnoreCase("html")) {
            return "text/html";
        }
        if (filenameExtension.equalsIgnoreCase("txt")) {
            return "text/plain";
        }
        if (filenameExtension.equalsIgnoreCase("vsd")) {
            return "application/vnd.visio";
        }
        if (filenameExtension.equalsIgnoreCase("pptx") || filenameExtension.equalsIgnoreCase("ppt")) {
            return "application/vnd.ms-powerpoint";
        }
        if (filenameExtension.equalsIgnoreCase("docx") || filenameExtension.equalsIgnoreCase("doc")) {
            return "application/msword";
        }
        if (filenameExtension.equalsIgnoreCase("xml")) {
            return "text/xml";
        }
        return "image/jpeg";
    }

    /**
     * 获得url链接
     *
     * @param key
     * @return
     */
    public static String getUrl(String key) {
        if(StrKit.notBlank(key)){
            // 设置URL过期时间为10年 3600l* 1000*24*365*10

            Date expiration = new Date(System.currentTimeMillis() + 3600L * 1000 * 24 * 365 * 10);
            // 生成URL
            URL url = getOSSClient().generatePresignedUrl(bucketName, key, expiration);
            if (url != null) {
                return url.toString();
            }
        }
        return null;
    }

}
